package org.jetlinks.community.mstn.service;

import lombok.AllArgsConstructor;
import org.hswebframework.ezorm.core.param.QueryParam;
import org.hswebframework.ezorm.core.param.Term;
import org.hswebframework.utils.StringUtils;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.hswebframework.web.api.crud.entity.QueryParamEntity;
import org.hswebframework.web.crud.service.GenericReactiveCrudService;
import org.hswebframework.web.id.IDGenerator;
import org.jetlinks.community.elastic.search.index.*;
import org.jetlinks.community.elastic.search.service.ElasticSearchService;
import org.jetlinks.community.mstn.entity.CustomFormEntity;
import org.jetlinks.community.mstn.entity.CustomFormLogEntity;
import org.jetlinks.community.timeseries.TimeSeriesData;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.util.List;
import java.util.Map;

@Service
@AllArgsConstructor
public class CustomFormService extends GenericReactiveCrudService<CustomFormEntity, String> {


    private final ElasticSearchService elasticSearchService;

    private final ElasticSearchIndexManager indexManager;


    /**
     * 保存上传的数据
     * @param formId
     * @param customFormLogEntity
     * @return
     */
    public Mono<Void> saveUploadData(String formId, CustomFormLogEntity customFormLogEntity){
        return indexManager.getIndexMetadata(getMetricsName(formId))
            .switchIfEmpty(Mono.defer(() -> createMetadata(formId)))
            .then(Mono.defer(() -> {
                customFormLogEntity.setId(IDGenerator.SNOW_FLAKE_STRING.generate());
                customFormLogEntity.setTimestamp(System.currentTimeMillis());
                return elasticSearchService.save(getMetricsName(formId), customFormLogEntity.toSimpleMap());
            }));
    }

    /**
     * 创建索引模板
     * @param formId
     * @return
     */
    public Mono<ElasticSearchIndexMetadata> createMetadata(String formId){
        ElasticSearchIndexMetadata indexMetadata = new DefaultElasticSearchIndexMetadata(getMetricsName(formId), CustomFormLogEntity.getProperties());
        return indexManager.putIndex(indexMetadata)
            .thenReturn(indexMetadata);
    }
    /**
     * 修改上传的数据
     * @param formId
     * @param customFormLogEntity
     * @return
     */
    public Mono<Void> updateUploadData(String formId, CustomFormLogEntity customFormLogEntity){
        return queryUploadDataById(formId, customFormLogEntity.getId())
                .switchIfEmpty(Mono.error(new RuntimeException("id不存在")))
                .map(oldEntity -> merge(customFormLogEntity,oldEntity))
                .doOnNext(current -> {
                    deleteUploadDataById(formId, current.getId());
                })
                .flatMap(current -> elasticSearchService.save(getMetricsName(formId), current.toSimpleMap()))

            ;
    }


    /**
     * 查询数据
     * @param formId
     * @param id
     * @return
     */
    public Mono<CustomFormLogEntity> queryUploadDataById(String formId, String id){
        QueryParam query = new QueryParam();
        query.setPaging(false);
        List<Term> terms = query.getTerms();
        Term term = new Term();
        term.setColumn("id");
        term.setValue(id);
        term.setTermType("eq");
        terms.add(term);
        query.setTerms(terms);
        return elasticSearchService.query(
                    getMetricsName(formId),
                    query,
                    CustomFormLogEntity.class)
            .singleOrEmpty();

    }

    /**
     * 删除数据
     * @param formId
     * @param id
     * @return
     */
    public Mono<Long> deleteUploadDataById(String formId, String id){
        QueryParamEntity query = new QueryParamEntity();
        query.setWhere("_id =" + id);
        return elasticSearchService.delete(getMetricsName(formId), query);

    }

    /**
     * 查询上传的数据
     * @param formId
     * @return
     */
    public Mono<PagerResult<CustomFormLogEntity>> queryUploadData(String formId, QueryParamEntity query){
        return elasticSearchService.queryPager(getMetricsName(formId),query,CustomFormLogEntity.class);
    }

    /**
     * 获取es表名字
     * @param formId
     * @return
     */
    private String getMetricsName(String formId){
        return "form_log_".concat(formId);
    }

    /**
     * 修改合并数据
     * @param customFormLogEntity
     * @param oldCustomFormLogEntity
     * @return
     */
    private CustomFormLogEntity merge(CustomFormLogEntity customFormLogEntity,CustomFormLogEntity oldCustomFormLogEntity){
        if (!StringUtils.isNullOrEmpty(customFormLogEntity.getOrgId())) {
            oldCustomFormLogEntity.setOrgId(customFormLogEntity.getOrgId());
        }
        if (!StringUtils.isNullOrEmpty(customFormLogEntity.getType())) {
            oldCustomFormLogEntity.setType(customFormLogEntity.getType());
        }
        if (!StringUtils.isNullOrEmpty(customFormLogEntity.getCreateTime())) {
            oldCustomFormLogEntity.setCreateTime(customFormLogEntity.getCreateTime());
        }

        if (!StringUtils.isNullOrEmpty(customFormLogEntity.getContent())) {
            oldCustomFormLogEntity.setContent(customFormLogEntity.getContent());
        }
        return oldCustomFormLogEntity;
    }
}
